﻿using CommonTools.Extension;
using CommonTools.Util;
using Discord;
using Discord.Response;
using Microsoft.AspNetCore.Mvc;
using ViewModel.Enum;
using ViewModel.Param;
using ViewModel.Response;

namespace MidJourneyApi.Controllers
{
    [ApiController]
    public class TaskController : ControllerBase
    {
        /// <summary>
        /// 绘制
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/imagine")]
        [HttpPost]
        public IActionResult Imagine([FromBody] TriggerImagineIn param)
        {
            (string triggerId, string prompt) = DiscordUtil.Prompt(param.Prompt, param.PicUrl);
            string triggerType = TriggerType.Generate.GetEnumText();
            TaskQueue.Instance.Put(triggerId, DiscordApi.Generate, prompt);
            return new JsonResult(new TriggerResponse
            {
                TriggerId = triggerId,
                TriggerType = triggerType
            });
        }

        /// <summary>
        /// 放大指定图片
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/upscale")]
        [HttpPost]
        public IActionResult Upscale([FromBody] TriggerUVIn param)
        {
            string triggerId = param.TriggerId;
            string triggerType = TriggerType.Upscale.GetEnumText();
            TaskQueue.Instance.Put(triggerId, DiscordApi.Upscale, param.Index, param.MsgId, param.MsgHash);
            return new JsonResult(new TriggerResponse
            {
                TriggerId = triggerId,
                TriggerType = triggerType
            });
        }

        /// <summary>
        /// 优化指定图片
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/variation")]
        [HttpPost]
        public IActionResult Variation([FromBody] TriggerUVIn param)
        {
            string triggerId = param.TriggerId;
            string triggerType = TriggerType.Variation.GetEnumText();
            TaskQueue.Instance.Put(triggerId, DiscordApi.Variation, param.Index, param.MsgId, param.MsgHash);
            return new JsonResult(new TriggerResponse
            {
                TriggerId = triggerId,
                TriggerType = triggerType
            });
        }

        /// <summary>
        /// 重新绘制
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/reset")]
        [HttpPost]
        public IActionResult Reset([FromBody] TriggerResetIn param)
        {
            string triggerId = param.TriggerId;
            string triggerType = TriggerType.Reset.GetEnumText();
            TaskQueue.Instance.Put(triggerId, DiscordApi.Reset, param.MsgId, param.MsgHash);
            return new JsonResult(new TriggerResponse
            {
                TriggerId = triggerId,
                TriggerType = triggerType
            });
        }

        /// <summary>
        /// 做出变化
        /// 对upscale的单张图片进行“Make Variations”操作
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/solovariation")]
        [HttpPost]
        public IActionResult SoloVariation([FromBody] TriggerSoloIn param)
        {
            string triggerId = param.TriggerId;
            string triggerType = TriggerType.SoloVariation.GetEnumText();
            TaskQueue.Instance.Put(triggerId, DiscordApi.SoloVariation, param.MsgId, param.MsgHash);
            return new JsonResult(new TriggerResponse
            {
                TriggerId = triggerId,
                TriggerType = triggerType
            });
        }

        /// <summary>
        /// 变化（细微）
        /// 对upscale的单张图片进行“Vary(Subtle)”操作
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/sololowvariation")]
        [HttpPost]
        public IActionResult SoloLowVariation([FromBody] TriggerSoloIn param)
        {
            string triggerId = param.TriggerId;
            string triggerType = TriggerType.SoloLowVariation.GetEnumText();
            TaskQueue.Instance.Put(triggerId, DiscordApi.SoloLowVariation, param.MsgId, param.MsgHash);
            return new JsonResult(new TriggerResponse
            {
                TriggerId = triggerId,
                TriggerType = triggerType
            });
        }

        /// <summary>
        /// 变化（强）
        /// 对upscale的单张图片进行“Vary(Strong)”操作
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/solohighvariation")]
        [HttpPost]
        public IActionResult SoloHighVariation([FromBody] TriggerSoloIn param)
        {
            string triggerId = param.TriggerId;
            string triggerType = TriggerType.SoloHighVariation.GetEnumText();
            TaskQueue.Instance.Put(triggerId, DiscordApi.SoloHighVariation, param.MsgId, param.MsgHash);
            return new JsonResult(new TriggerResponse
            {
                TriggerId = triggerId,
                TriggerType = triggerType
            });
        }

        /// <summary>
        /// ⬅️➡️⬆️⬇️
        /// 对upscale单张图片进行某个方向的操作扩展
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/expand")]
        [HttpPost]
        public IActionResult Expand([FromBody] TriggerExpandIn param)
        {
            string triggerId = param.TriggerId;
            string triggerType = TriggerType.Expand.GetEnumText();
            TaskQueue.Instance.Put(triggerId, DiscordApi.Expand, param.MsgId, param.MsgHash, param.Direction);
            return new JsonResult(new TriggerResponse
            {
                TriggerId = triggerId,
                TriggerType = triggerType
            });
        }

        /// <summary>
        /// 缩小2倍/1.5倍
        /// 对upscale的单张图片进行缩小2x/1.5x操作
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/zoomout")]
        [HttpPost]
        public IActionResult ZoomOut([FromBody] TriggerZoomOutIn param)
        {
            string triggerId = param.TriggerId;
            string triggerType = TriggerType.ZoomOut.GetEnumText();
            TaskQueue.Instance.Put(triggerId, DiscordApi.ZoomOut, param.ZoomOut, param.MsgId, param.MsgHash);
            return new JsonResult(new TriggerResponse
            {
                TriggerId = triggerId,
                TriggerType = triggerType
            });
        }

        /// <summary>
        /// 图片会说话
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/describe")]
        [HttpPost]
        public IActionResult Describe([FromBody] TriggerDescribeIn param)
        {
            string triggerId = param.TriggerId;
            string triggerType = TriggerType.Describe.GetEnumText();
            TaskQueue.Instance.Put(triggerId, DiscordApi.Describe, param.UpLoadFileName);
            return new JsonResult(new TriggerResponse
            {
                TriggerId = triggerId,
                TriggerType = triggerType
            });
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/upload")]
        [HttpPost]
        public async Task<IActionResult> Upload(IFormFile file)
        {
            var result = new UploadResponse();
            if (!file.ContentType.StartsWith("image/"))
            {
                result.Message = "must image";
                return new JsonResult(result);
            }

            string triggerId = DiscordUtil.GenerateUniqueId();
            string fileName = $"{triggerId}.jpg";
            long fileSize = file.Length;

            var path = Path.Combine(Directory.GetCurrentDirectory(), "uploads/" + fileName);

            await using (var stream = new FileStream(path, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }

            (bool status, UploadData ret) = await DiscordApi.UploadAttachment(fileName, (int)fileSize, path);

            if (!status || string.IsNullOrEmpty(ret.UploadUrl))
            {
                result.Message = "Failed to upload image";
                return new JsonResult(result);
            }

            result.TriggerId = triggerId;
            result.UpLoadFileName = ret.UploadFileName;
            result.UpLoadUrl = ret.UploadUrl;
            return new JsonResult(result);
        }

        /// <summary>
        /// 发送图片
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [Route("v1/api/trigger/message")]
        [HttpPost]
        public async Task<IActionResult> SendMessage([FromBody] SendMessageIn param)
        {
            var result = new SendMessageResponse();
            (bool status, string picUrl) = await DiscordApi.SendAttachmentMessage(param.UpLoadFileName);

            if (!status || string.IsNullOrEmpty(picUrl))
            {
                result.Message = "Failed to send message";
                return new JsonResult(result);
            }
            result.PicUrl = picUrl;
            return new JsonResult(result);
        }
    }
}
